﻿#include "GUIFESubSystemRemeshDialog.h"
#include "ui_GUIFESubSystemRemeshDialog.h"

#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractFESubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKFESubSysGeoProp.h"

#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

// Pick
#include "PickDataProvider/GUIPickInfo.h"
#include "PickDataProvider/PickedDataProvider.h"
#include "PickDataProvider/PickedData.h"

#include <QButtonGroup>
#include <QRegExpValidator>
#include <QTabBar>

namespace GUI {

    GUIFESubSystemRemeshDialog::GUIFESubSystemRemeshDialog(Core::FITKActionOperator* oper, QWidget* parent /*= nullptr*/) :
        GUIDialogBase(parent),
        _oper(oper),
        _ui(new Ui::GUIFESubSystemRemeshDialog)
    {
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        //绑定拾取信号
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        //清除拾取对象所有的连接
        QObject::disconnect(pickProvider, SIGNAL(sig_pickedOver()), nullptr, nullptr);
        if (pickProvider)
            connect(pickProvider, &GraphData::PickedDataProvider::sig_pickedOver, this, &GUIFESubSystemRemeshDialog::pickDataFinished);
        //初始化
        this->init();
    }

    GUIFESubSystemRemeshDialog::~GUIFESubSystemRemeshDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }

    void GUIFESubSystemRemeshDialog::init()
    {
        //初始化界面
        _ui->comboBox_PickType->addItem(tr("FE Structure"), GUI::GUIPickInfo::PickObjType::POBJFEStructure);
        _ui->comboBox_PickType->addItem(tr("FE Cavity"), GUI::GUIPickInfo::PickObjType::POBJFEAcoustic);
        _ui->comboBox_PickType->setCurrentIndex(0);
        _ui->radioButton_EleLength->setChecked(true);
        _ui->radioButton_ShellTri->setChecked(true);
        _ui->radioButton_Boundary->setChecked(true);
        //设置单元大小
        _ui->lineEdit_EleLength->setText("0.00877458");
        _ui->lineEdit_EleNumber->setText("0");
    }

    void GUIFESubSystemRemeshDialog::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void GUIFESubSystemRemeshDialog::on_pushButton_OK_clicked()
    {
        double sizeMesh = _ui->lineEdit_EleLength->text().toDouble();
        int numMesh = _ui->lineEdit_EleNumber->text().toInt();
        bool isFixedBoundary = _ui->radioButton_Boundary->isChecked();
        bool isTri = _ui->radioButton_ShellTri->isChecked();
        if (_oper && _subSysObj)
        {
            _oper->setArgs("MeshSize", sizeMesh);
            _oper->setArgs("MeshNumber", numMesh);
            _oper->setArgs("pickDataObjID", _subSysObj->getDataObjectID());
            _oper->setArgs("IsFixedBoundary", isFixedBoundary);
            _oper->setArgs("IsTri", isTri);
        }
        this->accept();
    }

    void GUIFESubSystemRemeshDialog::on_comboBox_PickType_currentIndexChanged(int index)
    {
        GUI::GUIPickInfo::PickObjType pickType = GUI::GUIPickInfo::PickObjType(_ui->comboBox_PickType->currentData().toInt());
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMSingle;
        pickInfo._pickObjType = pickType;
        //结构
        if (pickType == GUI::GUIPickInfo::PickObjType::POBJFEStructure)
        {
            _ui->groupBox_Node->setEnabled(true);
            _ui->groupBox_ShellType->setEnabled(true);
        }
        //腔体
        else if (pickType == GUI::GUIPickInfo::PickObjType::POBJFEAcoustic)
        {
            _ui->groupBox_Node->setEnabled(false);
            _ui->groupBox_ShellType->setEnabled(false);
        }
        //设置拾取类型
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }

    void GUIFESubSystemRemeshDialog::on_radioButton_EleNumber_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_EleLength->setEnabled(false);
            _ui->lineEdit_EleNumber->setEnabled(true);
        }
    }

    void GUIFESubSystemRemeshDialog::on_radioButton_EleLength_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_EleNumber->setEnabled(false);
            _ui->lineEdit_EleLength->setEnabled(true);
        }
    }

    void GUIFESubSystemRemeshDialog::on_lineEdit_EleLength_textChanged(QString text)
    {
        double size = text.toDouble();
        if (_subSysObj == nullptr || size < 1e-15) return;
        Acoustics::FITKFESubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (!geoProp) return;
        //阻塞信号触发
        _ui->lineEdit_EleNumber->blockSignals(true);
        //获取维度
        int dim = _subSysObj->getElementDim();
        if (dim == 1)
        {
            //获取周长
            double circ = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Circumference);
            int num = circ / size;
            _ui->lineEdit_EleNumber->setText(QString::number(num));
        }
        else if (dim == 2)
        {
            //获取面积
            double area = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Area);
            int num = area / (sqrt(3) * size * size / 4);
            _ui->lineEdit_EleNumber->setText(QString::number(num));
        }
        else if (dim == 3)
        {
            //获取体积
            double volume = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Volume);
            int num = volume / (sqrt(3) * size * size * size / 24);
            _ui->lineEdit_EleNumber->setText(QString::number(num));
        }
        _ui->lineEdit_EleNumber->blockSignals(false);
    }

    void GUIFESubSystemRemeshDialog::on_lineEdit_EleNumber_textChanged(QString text)
    {
        int number = text.toDouble();
        if (_subSysObj == nullptr || number <= 0) return;
        Acoustics::FITKFESubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (!geoProp) return;
        //阻塞信号触发
        _ui->lineEdit_EleLength->blockSignals(true);
        //获取维度
        int dim = _subSysObj->getElementDim();
        if (dim == 1)
        {
            //获取周长
            double circ = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Circumference);
            double size = circ / number;
            _ui->lineEdit_EleLength->setText(QString::number(size));
        }
        else if (dim == 2)
        {
            //获取面积
            double area = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Area);
            double size = sqrt(area / number * 4 / sqrt(3));
            _ui->lineEdit_EleLength->setText(QString::number(size));
        }
        else if (dim == 3)
        {
            //获取体积
            double volume = geoProp->getGeoProp(Acoustics::FITKFESubSysGeoProp::FESubSysGeoPropType::Volume);
            int size = pow(volume / number * 24 / sqrt(3), 1.0 / 3);
            _ui->lineEdit_EleLength->setText(QString::number(size));
        }
        _ui->lineEdit_EleLength->blockSignals(false);
    }

    void GUIFESubSystemRemeshDialog::reject()
    {
        //清除拾取模式和高亮
        GUI::GUIPickInfo::ClearPickInfo();
        this->QDialog::reject();
    }

    void GUIFESubSystemRemeshDialog::pickDataFinished()
    {
        //获取三维可视化对象管理
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider)return;
        //获取拾取数据对象
        QList<GraphData::PickedData*> pickList = pickProvider->getPickedList();
        //拾取FE数据ID
        int objID = -1;
        for (GraphData::PickedData* pickData : pickList)
        {
            if (!pickData) continue;
            objID = pickData->getPickedDataObjId();
        }
        //获取节点管理器 
        Acoustics::FITKAcousticsDiscModel *discModel = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discModel) return;
        //获取板的数据
        Acoustics::FITKAcousticsFEModel* feModel = discModel->getFEModel();
        if (!feModel)return;
        Acoustics::FITKAcousticsFESubSysManager* subSysMgr = feModel->getFESubSysManager();
        if (!subSysMgr) return;
        _subSysObj = subSysMgr->getDataByID(objID);
        //更新尺寸
        if (_ui->radioButton_EleLength->isChecked())
            this->on_lineEdit_EleLength_textChanged(_ui->lineEdit_EleLength->text());
        else
            this->on_lineEdit_EleNumber_textChanged(_ui->lineEdit_EleNumber->text());
    }
}
